home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Toolbox
/
Visual Basic Toolbox (P.I.E.)(1996).ISO
/
graphics
/
manyth31
/
mnythdll.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-07
|
14KB
|
582 lines
/*
Mnythdll.dll -- 7-31-94, Bruce McLean
DLL for manythings screen saver, includes routines:
1) ManyDibLoad -- reads DIB files into memory
2) ManyGifLoad -- reads GIF files into memory and converting to
DIB format
3) ManyDibWrite -- writes DIB file in memory out to a file
4) ManyDibModPalette -- adds offsets to colors in palette
5) ManyDibCyclePalette -- shifts palette entries
6) ManyLoadLogPal -- retrieves DIB palette into a LOGPALETTE
structure
7) ManyDibGet -- returns pointer to DIB in memory
8) ManyDibGetData -- returns pointer to bitmap data area of DIB in memory
9) ManyDibFree -- frees memory used by DIB in memory
Warnings --
C++ by default modifies the names of functions to add parameter type
information, to make the functions callable by Visual Basic they need
to be declared as 'extern "C"' and 'pascal _export'. See Mnythdll.h
for example.
To use the project file, Directories under the Options menu will have to
be changed.
*/
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>
#include <stdio.h>
#include "mnythdll.h" // function prototypes for declaring as exported "C"
#include "bitmaps.h"
#include "gif.h"
#define MIN(a,b) ((a) < (b) ? (a) : (b))
// static DIB data
BYTE huge * DIBPointer;
int Width,Height;
const int NumColors = 256;
// Write DIB to a file from memory, returns 0 on no error
int FAR pascal _export ManyDibWrite (const FAR char * szFileName)
{
FILE * WriteFile;
if(DIBPointer == NULL)
{
return 1;
}
WriteFile = fopen(szFileName,"wb");
if(WriteFile == NULL)
{
return 2;
}
// get header pointer
BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
// get total file size
unsigned long Size = sizeof(BITMAPFILEHEADER) + BMapHeader->biSize
+ BMapHeader->biClrUsed * sizeof (RGBQUAD) + BMapHeader->biSizeImage;
//write type to file
fputc('B',WriteFile);
fputc('M',WriteFile);
fwrite(&Size,4,1,WriteFile); // store file size
// file reserved fields
fputc(0,WriteFile);
fputc(0,WriteFile);
fputc(0,WriteFile);
fputc(0,WriteFile);
// get offset to data bits
unsigned long Offset = sizeof(BITMAPFILEHEADER) + BMapHeader->biSize
+ BMapHeader->biClrUsed * sizeof (RGBQUAD);
fwrite(&Offset,4,1,WriteFile); // store file size
//write dib
const unsigned int WriteMaxSize = 32768u;
unsigned long DibSize = BMapHeader->biSize + BMapHeader->biSizeImage
+ BMapHeader->biClrUsed * sizeof (RGBQUAD);
unsigned int BlockSize;
BYTE huge * OutPointer = DIBPointer;
while(DibSize > 0)
{
if(DibSize > WriteMaxSize)
{
BlockSize = WriteMaxSize;
}
else
{
BlockSize = (unsigned int) DibSize;
}
fwrite(OutPointer,BlockSize,1,WriteFile); // store dib data
DibSize -= BlockSize;
OutPointer += BlockSize;
} // while end
fclose(WriteFile);
return 0; // success
}
// Read a dib palette into Logical palette for Vbasic
void pascal _export ManyLoadLogPal (LOGPALETTE & Pal,int Start,int MaxSize,int Flags)
{
Pal.palVersion = 0x0300;
if( DIBPointer == NULL )
{
Pal.palNumEntries = 0;
return;
}
// get header pointer
BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
// get Palette pointer
BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
BYTE huge * BPtr;
Pal.palNumEntries = BMapHeader->biClrUsed;
// check for funny palette size
if( (Pal.palNumEntries <= 0) || (Pal.palNumEntries >256) )
{
Pal.palNumEntries = 0;
return;
}
if(Pal.palNumEntries > MaxSize)
{
Pal.palNumEntries = MaxSize;
}
Pal.palNumEntries -= Start; // subtract off entries skipped
// extract palette
for(int i=0;i<Pal.palNumEntries;i++)
{
BPtr = Palette + (i+Start)*4; // get address of palette entry
Pal.palPalEntry[i].peRed = *(BPtr+2);
Pal.palPalEntry[i].peGreen = *(BPtr+1);
Pal.palPalEntry[i].peBlue = (*BPtr);
Pal.palPalEntry[i].peFlags = Flags;
// set flags in palete
*(BPtr+3) = Flags;
}
} // end ManyLoadLogPal
// Read a GIF from a file into memory
long FAR pascal _export ManyGifLoad (const FAR char * szFileName,int FAR * width,int FAR * height)
{
int i = ManyDibFree();
if(i != 0) // free memory
{
return -6-i; // error codes 1 to n are mapped to -7 to -7-n
}
// read gif file into memory
HDIB DibHandle = ReadGifFile(szFileName);
if(DibHandle == NULL)
{
return -1;
}
BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) GlobalLock(DibHandle);
DIBPointer = (BYTE huge *) BMapHeader;
if(DIBPointer == NULL)
{
return -2;
}
// check if wrong style dib
if ((BMapHeader->biSize != 0x28 ) // check for funny header size
|| (BMapHeader->biPlanes != 1) // check for multiple planes
|| (BMapHeader->biBitCount != 8) // make sure 256 color
|| (BMapHeader->biClrUsed > 256) // check for consistency
|| (BMapHeader->biClrUsed <= 0) ) // check for consistency
{
ManyDibFree(); // free memory
return -5 ;
}
int Width = (int) BMapHeader->biWidth;
int Height = (int) BMapHeader->biHeight;
*height = Height;
*width = Width;
return (long) DIBPointer ;
} // end ManyGifLoad
// Read a DIB from a file into memory
long FAR pascal _export ManyDibLoad (const FAR char * szFileName,int FAR * width,int FAR * height)
{
BITMAPFILEHEADER bmfh ;
DWORD dwDibSize, dwOffset;
int hFile ;
WORD wDibRead ;
int i = ManyDibFree();
if(i != 0) // free memory
{
return -6-i; // error codes 1 to n are mapped to -7 to -7-n
}
// try to open file
if (-1 == (hFile = _lopen (szFileName, OF_READ | OF_SHARE_DENY_WRITE)))
{
return -6 ;
}
if (_lread (hFile, (LPSTR) &bmfh, sizeof (BITMAPFILEHEADER)) !=
sizeof (BITMAPFILEHEADER))
{
_lclose (hFile) ;
return -1 ;
}
if (bmfh.bfType != * (WORD *) "BM")
{
_lclose (hFile) ;
return -2 ;
}
dwDibSize = bmfh.bfSize - sizeof (BITMAPFILEHEADER) ;
DIBPointer = (BYTE huge * ) GlobalAllocPtr (GMEM_MOVEABLE, dwDibSize) ;
if (DIBPointer == NULL)
{
_lclose (hFile) ;
return -3 ;
}
dwOffset = 0 ;
while (dwDibSize > 0)
{
wDibRead = (WORD) MIN (32768ul, dwDibSize) ;
if (wDibRead != _lread (hFile, (LPSTR) (DIBPointer + dwOffset), wDibRead))
{
_lclose (hFile) ;
ManyDibFree();
return -4 ;
}
dwDibSize -= wDibRead ;
dwOffset += wDibRead ;
}
_lclose (hFile) ;
BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
// check if wrong style dib
if ((BMapHeader->biSize != 0x28 ) // check for funny header size
|| (BMapHeader->biPlanes != 1) // check for multiple planes
|| (BMapHeader->biBitCount != 8) // make sure 256 color
|| (BMapHeader->biClrUsed > 256) // check for consistency
|| (BMapHeader->biClrUsed <= 0) ) // check for consistency
{
ManyDibFree();
return -5 ;
}
Width = (int) BMapHeader->biWidth;
Height = (int) BMapHeader->biHeight;
*height = Height;
*width = Width;
return (long) DIBPointer ;
}
// returns pointer to memory for DIB data bytes
long FAR pascal _export ManyDibGetData( void )
{
if(DIBPointer == NULL) // see if not allocated
{
return NULL;
}
// get header pointer
BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
// get Palette pointer
BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
// get data pointer
BYTE huge * DataBits = Palette + BMapHeader->biClrUsed * sizeof (RGBQUAD) ;
return (long) DataBits; // no error, return pointer to data
}
// returns pointer to memory for DIB bitmap, also is pointer to header
long FAR pascal _export ManyDibGet( void )
{
return (long) DIBPointer; // return pointer
}
// frees memory for DIB bitmap, returns 0 if successful
int FAR pascal _export ManyDibFree( void )
{
if(DIBPointer == NULL) // see if memory allocated
{
return 0; // no need to do anything
}
// try to unlock memory
//GlobalFreePtr (DIBPointer) ;
int i = GlobalUnlock(GlobalPtrHandle(DIBPointer));
if (i != NULL )
{
return 2;
}
// try to free memory
if(GlobalFree(GlobalPtrHandle(DIBPointer)) != NULL)
{
return 3;
}
DIBPointer = NULL; // clear pointer
return 0;
}
// modify all palettes
void FAR pascal _export ManyDibCyclePalette(int StepSize,int LowValue,int HighValue)
{
if(DIBPointer == NULL) // see if memory allocated
{
return; // no need to do anything
}
// get header pointer
BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
// get Palette pointer
BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
// limit values
if(LowValue<0)
{
LowValue = 0;
}
if(HighValue>BMapHeader->biClrUsed-1)
{
HighValue = (int) BMapHeader->biClrUsed-1;
}
long huge * LPtr;
int Steps = abs(StepSize);
for(int j = 0;j<Steps;j++)
{
if(StepSize>0) // if forward cycling
{
LPtr = (long huge *) ( Palette + 4*HighValue);
long Temp = *LPtr; // save first
for(int i= (int) HighValue;i>0;i--) // change palette
{
LPtr = (long huge *) ( Palette + 4*i);
*LPtr = *(LPtr-1); // shift palette entry down
}
LPtr = (long huge *) ( Palette + 4*LowValue);
*LPtr = Temp; // put in first entry
}
else // reverse cycle
{
LPtr = (long huge *) ( Palette + 4*LowValue);
long Temp = *LPtr; // save first
for(int i=LowValue+1;i<=HighValue;i++) // change palette
{
LPtr = (long huge *) ( Palette + 4*i);
*(LPtr-1) = *(LPtr); // shift palette entry down
}
LPtr = (long huge *) ( Palette + 4*HighValue);
*LPtr = Temp; // put in first entry
}
} // end for j
}
// modify all palettes
void FAR pascal _export ManyDibModPalette(int red,int green,int blue)
{
if(DIBPointer == NULL) // see if memory allocated
{
return; // no need to do anything
}
// get header pointer
BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
// get Palette pointer
BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
BYTE huge * BPtr;
for(int i=0;i<BMapHeader->biClrUsed;i++) // change palette
{
BPtr = (BYTE huge *) ( Palette + 4*i);
*(BPtr+2) += red;
*(BPtr+1) += green;
*(BPtr) += blue;
}
}
// initializes a previously created DIB, returns value less than 10 on error
// else returns pointer to data area
long FAR pascal _export ManyDibInit()
{
// check for invalid dib
if(DIBPointer == NULL) // not allocated
{
return 1;
}
if(Width == 0) // bad size
{
return 2;
}
if(Height == 0) // bad size
{
return 3;
}
// make sure we have enough room
long Size = sizeof(BITMAPFILEHEADER) + (long) Width * Height
+ NumColors * sizeof (RGBQUAD) ;
if(Size > GlobalSize(GlobalPtrHandle(DIBPointer)))
{
return 4;
}
BYTE huge * BPtr;
long huge * LPtr;
// get header pointer
BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
// get Palette pointer
BYTE huge * Palette = DIBPointer + BMapHeader->biSize;
// get data pointer
BYTE huge * DataBits = Palette + BMapHeader->biClrUsed * sizeof (RGBQUAD) ;
for(int i=0;i<BMapHeader->biClrUsed;i++) // initialize palette
{
LPtr = (long huge *) ( Palette + 4*i);
*LPtr = ((long) i<<16) + ((long) i<<8) + i; // store value in palette as long word
}
// initialize each line
for(i=0;i<Height;i++)
{
// for each column in row
for(int j=0;j<Width;j++)
{
BPtr = DataBits + (long) i * Width + j;
*BPtr = i+j; // store value in data
}
}
return (long) DataBits; // no error, return pointer to data
}
// creates a 256 color DIB bitmap with dimensions given
long FAR pascal _export ManyDibAlloc( int width,int height )
{
Width = width; Height = height; // save dimensions
long Size = sizeof (BITMAPFILEHEADER) + (long) width * height
+ NumColors * sizeof (RGBQUAD) + 256;
if(DIBPointer == NULL)
{
// allocate necessary memory
DIBPointer = (BYTE huge * ) GlobalAllocPtr(GMEM_MOVEABLE, Size) ;
}
else // now check for insufficient size
if(Size > GlobalSize(GlobalPtrHandle(DIBPointer)))
{
if(ManyDibFree() == 0) // try to free previously allocated mem
{
// allocate necessary memory
DIBPointer = (BYTE huge * ) GlobalAllocPtr(GMEM_MOVEABLE, Size) ;
}
else
{
Width = 0; Height = 0; // clear dimensions on error
return 0L;
}
}
// return size if allocated
if (DIBPointer == NULL)
{
Width = 0; Height = 0; // clear dimensions on error
return 0L;
}
else // initialize dib and return size of block
{
// get header pointer
BITMAPINFOHEADER huge * BMapHeader = (BITMAPINFOHEADER huge *) DIBPointer;
// initialize header
BMapHeader->biSize = sizeof(BITMAPINFOHEADER);
BMapHeader->biWidth = width;
BMapHeader->biHeight = height;
BMapHeader->biPlanes = 1;
BMapHeader->biBitCount = 8; // 8 bits per pixel
BMapHeader->biCompression = 0; // no compress
BMapHeader->biSizeImage = (long) width * height;
BMapHeader->biXPelsPerMeter = 0; // use default
BMapHeader->biYPelsPerMeter = 0; // use default
BMapHeader->biClrUsed = NumColors; // number of colors in image
BMapHeader->biClrImportant = NumColors;
return GlobalSize(GlobalPtrHandle(DIBPointer));
}
}
// this procedure is called when DLL initialized
#pragma argsused
int FAR PASCAL LibMain( HINSTANCE hInstance,
WORD wDataSegment,
WORD wHeapSize,
LPSTR lpszCmdLine )
{
if ( wHeapSize != 0 )
{
UnlockData( 0 );
}
DIBPointer = NULL; // pointer starts out to be NULL
return 1;
}
#pragma argsused
int FAR PASCAL WEP ( int bSystemExit )
{
return 1;
}